package com.pmcc.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class DateUtil {

    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYYMMDD = "yyyyMMdd";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYY_MM_DD_HH_MM_SS_MS = "yyyy-MM-dd HH:mm:ss.ms";
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public final static int YEAR = 1;
    public final static int MONTH = 2;

    public static SimpleDateFormat getDateFormat(String parttern)
            throws RuntimeException {
        return new SimpleDateFormat(parttern);
    }

    /**
     * 时间转指定格式字符串
     *
     * @param date
     * @param parttern
     * @return
     */
    public static String DateToString(Date date, String parttern) {
        String formatDate = null;
        if (date != null) {
            try {
                if (parttern == null || "".equals(parttern)) {
                    parttern = YYYY_MM_DD_HH_MM_SS;
                }
                formatDate = getDateFormat(parttern).format(date);
            } catch (Exception e) {
                formatDate = new String();
            }
        }
        return formatDate;
    }

    /**
     * 字符串转指定格式时间
     *
     * @param date
     * @param parttern
     * @return
     */
    public static Date StringToDate(String date, String parttern) {
        Date formatDate = null;
        if (date != null) {
            try {
                if (parttern == null || "".equals(parttern)) {
                    parttern = YYYY_MM_DD_HH_MM_SS;
                }
                formatDate = getDateFormat(parttern).parse(date);
            } catch (Exception e) {
                formatDate = new Date();
            }
        }
        return new Date(formatDate.getTime());
    }

    /**
     * 获取一月的开始和结束日期
     *
     * @param time
     * @return
     */
    public static Date[] getBetweenMonthTime(Date time) {
        Date[] times = new Date[2];
        times[0] = getMonthStartTime(time);
        times[1] = getMonthEndTime(time);
        return times;
    }

    /**
     * 获取一天的开始和结束时间
     *
     * @param time
     * @return
     */
    public static Date[] getBetweenDayTime(Date time) {
        Date[] times = new Date[2];
        times[0] = getStartDayTime(time);
        times[1] = getEndDayTime(time);
        return times;
    }

    /**
     * 获取一年的开始和结束时间
     *
     * @param time
     * @return
     */
    public static Date[] getBetweenYearTime(Date time) {
        Date[] times = new Date[2];
        times[0] = getYearStartTime(time);
        times[1] = getYearEndTime(time);
        return times;
    }

    /**
     * 获取某天的开始时间
     *
     * @param time
     * @return
     */
    public static Date getStartDayTime(Date time) {
        // TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return new Date(c.getTime().getTime());
    }

    /**
     * 获取某天的结束时间
     *
     * @param time
     * @return
     */
    public static Date getEndDayTime(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return new Date(c.getTime().getTime());
    }

    /**
     * 获取某月的开始时间
     *
     * @param time
     * @return
     */
    public static Date getMonthStartTime(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        c.set(Calendar.DATE, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取某月的结束时间
     *
     * @param time
     * @return
     */
    public static Date getMonthEndTime(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        c.set(Calendar.DATE, 1);
        c.add(Calendar.MONTH, 1);
        c.add(Calendar.DAY_OF_MONTH, -1);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取某年的开始时间
     *
     * @param time
     * @return
     */
    public static Date getYearStartTime(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        c.set(Calendar.MONTH, 0);
        c.set(Calendar.DATE, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取某年的结束时间
     *
     * @param time
     * @return
     */
    public static Date getYearEndTime(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        c.set(Calendar.MONTH, 11);
        c.set(Calendar.DATE, 31);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 判断日期是否为空
     *
     * @param time
     * @return
     */
    private static Date isNullDate(Date time) {
        if (time == null) {
            return getCurrentTime();
        }
        return time;
    }

    /**
     * 获取当前时间
     *
     * @return Date
     */
    public static Date getCurrentTime() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取当前时间
     *
     * @return yyyy-MM-dd
     */
    public static String getCurrentTimeString() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return DateToString(c.getTime(), YYYY_MM_DD);
    }

    public static String getCurrentTimeYMDHMS() {
        return DateToString(new Date(), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取时间
     *
     * @param year  数字
     * @param month 数字
     * @return
     */
    public static Date getTime(int year, int month) {
        Calendar c = Calendar.getInstance();

        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month - 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    public static Date getTime(int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        if (year != 0) {
            c.set(Calendar.YEAR, year);
        }
        if (month != 0) {
            c.set(Calendar.MONTH, month - 1);
        }
        if (day != 0) {
            c.set(Calendar.DATE, day);
        }
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取时间
     *
     * @param time
     * @return 2014-04-1 00:00:00
     */
    public static Date getYMTime(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.set(Calendar.DATE, 0);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取时间
     *
     * @param time
     * @return 2014-04-5 00:00:00
     */
    public static Date getYMD(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取某个时间所在月的天数
     *
     * @param time
     * @return
     */
    public static int getNumberOfDay(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getActualMaximum(Calendar.DATE);
    }

    /**
     * 获取年
     *
     * @param time
     * @return
     */
    public static int getYear(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        return c.get(Calendar.YEAR);
    }

    /**
     * 获取月
     *
     * @param time
     * @return
     */
    public static int getMonth(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        c.setTime(time);
        return (c.get(Calendar.MONTH) + 1);
    }

    /**
     * 获取天
     *
     * @param time
     * @return
     */
    public static int getDay(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(isNullDate(time));
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 比较两个时间的大小
     *
     * @param oldDate
     * @param newDate
     * @return
     */
    public static int compareYM(Date oldDate, Date newDate) {
        long res = getYMTime(newDate).getTime() - getYMTime(oldDate).getTime();
        if (res > 0) {
            // 比之前日期大
            return 1;
        } else if (res == 0) {
            // 与之前日期相等
            return 0;
        } else {
            // 与之前日期小
            return -1;
        }

    }

    /**
     * 比较月份、天数
     *
     * @param date
     * @param now
     * @return
     */
    public static int compareMD(Date date, Date now) {

        Calendar dateC = Calendar.getInstance();
        dateC.setTime(date);
        int dateM = dateC.get(Calendar.MONTH);
        int dateD = dateC.get(Calendar.DAY_OF_MONTH);

        Calendar nowC = Calendar.getInstance();
        nowC.setTime(now);
        int nowM = nowC.get(Calendar.MONTH);
        int nowD = nowC.get(Calendar.DAY_OF_MONTH);

        if (dateM == nowM && dateD == nowD) {
            // 月份和天数相同
            return 1;
        } else {
            // 月份和天数不同
            return -1;
        }
    }

    public static int compareDate(Date date, Date now) {
        long res = now.getTime() - date.getTime();
        if (res > 0) {
            // 比之前日期大
            return 1;
        } else if (res == 0) {
            // 与之前日期相等
            return 0;
        } else {
            // 与之前日期小
            return -1;
        }

    }

    public static int compareTime(Date oldDate, Date newDate) {
        long res = newDate.getTime() - oldDate.getTime();
        if (res > 0) {
            // 比之前日期大
            return 1;
        } else if (res == 0) {
            // 与之前日期相等
            return 0;
        } else {
            // 与之前日期小
            return -1;
        }
    }

    /**
     * 增加天数
     *
     * @param time 时间
     * @param days 天数
     * @return
     */
    public static Date addDay(Date time, int days) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.DATE, days);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);

    }

    public static Date reduceDay(Date time, int days) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.set(Calendar.DATE, c.get(Calendar.DATE) - days);
        return StringToDate(DateToString(new Date(c.getTime().getTime()), YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);
    }


    public static Date addHour(Date time, int hours) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.HOUR, hours);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);

    }

    public static Date addMinute(Date time, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.MINUTE, minute);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);

    }

    /**
     * 增加月数
     *
     * @param time    时间
     * @param monthes 月
     * @return
     */
    public static Date addMonth(Date time, int monthes) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.MONTH, monthes);
        return StringToDate(
                DateToString(new Date(c.getTime().getTime()),
                        YYYY_MM_DD_HH_MM_SS), YYYY_MM_DD_HH_MM_SS);

    }


    /**
     * 计算天数
     *
     * @return
     */
    public static int betweenOfDay(Date time1, Date time2) {
        Calendar to1 = new GregorianCalendar();
        to1.setTime(time1);
        Calendar to2 = new GregorianCalendar();
        to2.setTime(time2);
        int res = to2.get(Calendar.DAY_OF_YEAR) - to1.get(Calendar.DAY_OF_YEAR);
        if (res < 0) {
            res = (res * -1);
        }
        return res;

    }

    public static Date getYesDate() {
        Date currentTime = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentTime);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        currentTime = calendar.getTime();
        return currentTime;
    }

    public static boolean weekend(Date date) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date == null ? new Date() : date);
        int i = calendar.get(Calendar.DAY_OF_WEEK);
        if (i == Calendar.SATURDAY || i == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }

    public static boolean weekend(String str) {

        Date date = new Date();
        if (str != null && !"".equals(str)) {
            date = StringToDate(str, YYYY_MM_DD);
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int i = calendar.get(Calendar.DAY_OF_WEEK);
        if (i == Calendar.SATURDAY || i == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }

    public static String add(Date date, int days) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.set(year, month, day, 0, 0, 0);

        final long OFFSET_MILLIS = days * 24 * 60 * 60 * 1000L;
        Date d = new Date(calendar.getTime().getTime() + OFFSET_MILLIS);

        return DateToString(d, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取两个日期之间的所有月份
     *
     * @param minDate
     * @param maxDate
     * @return
     * @throws ParseException
     */
    public static List<String> getMonthBetween(String minDate, String maxDate) throws ParseException {
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTime(sdf.parse(minDate));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTime(sdf.parse(maxDate));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }
        return result;
    }

    /**
     * 计算取消时间方法
     *
     * @param date       创建时间
     * @param cancelHour 未成团取消时间
     * @return
     */
    public static String countCancelTime(Date date, String cancelHour) {
        long time1 = date.getTime();
        long time2 = new Date().getTime();
        long temp = Long.parseLong(cancelHour) * 60 * 60 * 1000;
        return String.valueOf(time1 + temp - time2);
    }

    /**
     * 获取当前时间的前几天的集合
     *
     * @param count 时间点
     * @return
     */
    public static List<String> getDateQuantum(Integer count) {
        // 返回的日期集合
        List<String> days = new ArrayList<String>();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
//        cal.add(Calendar.DATE, -(count - 1));
        cal.add(Calendar.DATE, -count);
        Date start = cal.getTime();
//        Date end = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date end = calendar.getTime();

        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);

        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);
        tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
        while (tempStart.before(tempEnd)) {
            days.add(dateFormat.format(tempStart.getTime()));
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }
        return days;
    }

    /**
     * 获取日期
     *
     * @param amount 把日期往后增加一天.整数往后推,负数往前移动
     * @return
     */
    public static String getDate(int amount) {
        Date date = new Date();//取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, amount);
        date = calendar.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(date);
        System.out.println(dateString);
        return dateString;
    }

    public static void main(String[] args) {

        // 返回的日期集合
        List<String> days = new ArrayList<String>();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -6);
        Date start = cal.getTime();
        Date end = new Date();

        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);

        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);
        tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
        while (tempStart.before(tempEnd)) {
            days.add(dateFormat.format(tempStart.getTime()));
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }
        for (String temp : days) {
            System.out.println(temp);
        }


//        LocalDateTime now = LocalDateTime.now();
//        now = now.minus(90, ChronoUnit.DAYS);
//        System.out.println(now.toString());

        // TODO
//		System.out.println(DateToString(getYesDate(), YYYY_MM_DD_HH_MM_SS));
//        System.out.println(add(StringToDate("2017-04-07 10:20:09", YYYY_MM_DD_HH_MM_SS), 2));
    }

    /**
     * 计算今天周几
     * 说明：1：周日，2：周一，3：周二，4：周三，5：周四，6：周五，7：周六
     *
     * @param date
     * @return
     */
    public static int weekday(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_WEEK);
    }
    /**
     * 计算两个日期之间相差的天数
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate,Date bdate) throws ParseException
    {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 计算两个日期之间相差的小时，分钟，秒
     * @param endDate
     * @param nowDate
     * @return 相差 小时，分钟，秒
     * @throws ParseException
     */
    public static String getDatePoor(Date endDate, Date nowDate) {

        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long ns = 1000;

        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();

        // 计算差多少天
        long day = diff / nd;

        // 计算差多少小时
        long hour = diff % nd / nh;

        // 计算差多少分钟
        long min = diff % nd % nh / nm;

        // 计算差多少秒//输出结果
        long sec = diff % nd % nh % nm / ns;

        hour = day*24 +hour ;
        int a = (int) hour;
        String newHour = String.format("%02d", a);
        int b = (int) min;
        String newMin = String.format("%02d", b);
        int c = (int) sec;
        String newSec = String.format("%02d", c);


        return newHour + ":" + newMin + ":"+ newSec ;

    }

}